#ifndef LIS3DH_H
#define LIS3DH_H

#include <stdbool.h>
#include <stdint.h>

// ********************************************************************************

#define LIS3DH_RESERVED1_L 0x00
#define LIS3DH_RESERVED1_H 0x06
#define LIS3DH_STATUS_REG_AUX 0x07
#define LIS3DH_OUT_ADC1_L 0x08
#define LIS3DH_OUT_ADC1_H 0x09
#define LIS3DH_OUT_ADC2_L 0x0a
#define LIS3DH_OUT_ADC2_H 0x0b
#define LIS3DH_OUT_ADC3_L 0x0c
#define LIS3DH_OUT_ADC3_H 0x0d
#define LIS3DH_INT_COUNTER_REG 0x0e
#define LIS3DH_WHO_AM_I 0x0f
#define LIS3DH_RESERVED2_L 0x10
#define LIS3DH_RESERVED2_H 0x1e
#define LIS3DH_TEMP_CFG_REG 0x1f
#define LIS3DH_CTRL_REG1 0x20
#define LIS3DH_CTRL_REG2 0x21
#define LIS3DH_CTRL_REG3 0x22
#define LIS3DH_CTRL_REG4 0x23
#define LIS3DH_CTRL_REG5 0x24
#define LIS3DH_CTRL_REG6 0x25
#define LIS3DH_REFERENCE 0x26
#define LIS3DH_STATUS_REG2 0x27
#define LIS3DH_OUT_X_L 0x28
#define LIS3DH_OUT_X_H 0x29
#define LIS3DH_OUT_Y_L 0x2a
#define LIS3DH_OUT_Y_H 0x2b
#define LIS3DH_OUT_Z_L 0x2c
#define LIS3DH_OUT_Z_H 0x2d
#define LIS3DH_FIFO_CTRL_REG 0x2e
#define LIS3DH_FIFO_SRC_REG 0x2f
#define LIS3DH_INT1_CFG 0x30
#define LIS3DH_INT1_SRC 0x31
#define LIS3DH_INT1_THS 0x32
#define LIS3DH_INT1_DURATION 0x33
#define LIS3DH_RESERVED3_L 0x34
#define LIS3DH_RESERVED3_H 0x37
#define LIS3DH_CLICK_CFG 0x38
#define LIS3DH_CLICK_SRC 0x39
#define LIS3DH_CLICK_THS 0x3a
#define LIS3DH_TIME_LIMIT 0x3b
#define LIS3DH_TIME_LATENCY 0x3c
#define LIS3DH_TIME_WINDOW 0x3d
#define LIS3DH_RESERVED4_L 0x3e

#define LIS3DH_STATUS_REG_ZYXDA 0x08             // STATUS_REG: XYZ - sample ready
#define LIS3DH_STATUS_REG_ZYXOR 0x80             // STATUS_REG: XYZ - new set of data has overwritten the previous ones
#define LIS3DH_CTRL_REG1_XEN 0x01                // CTRL_REG1: X enable
#define LIS3DH_CTRL_REG1_YEN 0x02                // CTRL_REG1: Y enable
#define LIS3DH_CTRL_REG1_ZEN 0x04                // CTRL_REG1: Z enable
#define LIS3DH_CTRL_REG1_XYZEN 0x07              // CTRL_REG1: X+Y+Z enable
#define LIS3DH_CTRL_REG1_LPEN 0x08               // CTRL_REG1: Low power enable
#define LIS3DH_CTRL_REG1_DATARATE_POWERDOWN 0x00 // CTRL_REG1: 0000 xxxx
#define LIS3DH_CTRL_REG1_DATARATE_1HZ 0x10       // CTRL_REG1: 0001 xxxx
#define LIS3DH_CTRL_REG1_DATARATE_10HZ 0x20      // CTRL_REG1: 0010 xxxx
#define LIS3DH_CTRL_REG1_DATARATE_25HZ 0x30      // CTRL_REG1: 0011 xxxx
#define LIS3DH_CTRL_REG1_DATARATE_50HZ 0x40      // CTRL_REG1: 0100 xxxx
#define LIS3DH_CTRL_REG1_DATARATE_100HZ 0x50     // CTRL_REG1: 0101 xxxx
#define LIS3DH_CTRL_REG1_DATARATE_200HZ 0x60     // CTRL_REG1: 0110 xxxx
#define LIS3DH_CTRL_REG1_DATARATE_400HZ 0x70     // CTRL_REG1: 0111 xxxx
#define LIS3DH_CTRL_REG1_DATARATE_1500HZ 0x80    // CTRL_REG1: 1000 xxxx
#define LIS3DH_CTRL_REG1_DATARATE_5000HZ 0x90    // CTRL_REG1: 1001 xxxx
#define LIS3DH_CTRL_REG4_HR 0x08                 // CTRL_REG4: xxxx 1xxx
#define LIS3DH_CTRL_REG4_BLOCKDATAUPDATE 0x80    // CTRL_REG4: 1xxx xxxx
#define LIS3DH_CTRL_REG4_SCALE_2G 0x00           // CTRL_REG4: xx00 xxxx
#define LIS3DH_CTRL_REG4_SCALE_4G 0x10           // CTRL_REG4: xx01 xxxx
#define LIS3DH_CTRL_REG4_SCALE_8G 0x20           // CTRL_REG4: xx10 xxxx
#define LIS3DH_CTRL_REG4_SCALE_16G 0x30          // CTRL_REG4: xx11 xxxx
#define LIS3DH_CTRL_REG5_FIFO_EN 0x40            // CTRL_REG5: x1xx xxxx

#define LIS3DH_STATUSREG_XYZDA (1 << 3)

#define LIS3DH_WHO_AM_I_VAL 0x33

/* CTRL_REG1 definitions */
#define LIS3DH_HPM (0x03 << 6)
#define LIS3DH_HPIS1 (1 << 0)

/* CTRL_REG3 definitions */
#define LIS3DH_I1_INT1 (1 << 6)

/* INT1_CFG definitions */
#define LIS3DH_AOI (1 << 7)
#define LIS3DH_6D (1 << 6)
#define LIS3DH_ZHIE (1 << 5)
#define LIS3DH_ZLIE (1 << 4)
#define LIS3DH_YHIE (1 << 3)
#define LIS3DH_YLIE (1 << 2)
#define LIS3DH_XHIE (1 << 1)
#define LIS3DH_XLIE (1 << 0)

#define LIS3DH_MAX_DATA_RATE 5000
#define LIS3DH_MAX_FULL_SCALE 16000000
#define LIS3DH_MIN_FULL_SCALE 2000000

#define LIS3DH_SENSITIVITY_2G (0.001F)
#define LIS3DH_SENSITIVITY_4G (0.002F)
#define LIS3DH_SENSITIVITY_8G (0.004F)
#define LIS3DH_SENSITIVITY_16G (0.012F)

#define LIS3DH_READBIT (0x80)
#define LIS3DH_MSBIT (0x40)

// LIS3DH寄存器配置位
#define LIS3DH_CTRL_REG3_INT1_ENABLE 0x40
// INT1_CFG bit mask
#define LIS3DH_INT1_AND 0x80
#define LIS3DH_INT1_OR 0x00
#define LIS3DH_INT1_ZH_EN 0x20
#define LIS3DH_INT1_ZH_DIS 0x00
#define LIS3DH_INT1_ZL_EN 0x10
#define LIS3DH_INT1_ZL_DIS 0x00
#define LIS3DH_INT1_YH_EN 0x08
#define LIS3DH_INT1_YH_DIS 0x00
#define LIS3DH_INT1_YL_EN 0x04
#define LIS3DH_INT1_YL_DIS 0x00
#define LIS3DH_INT1_XH_EN 0x02
#define LIS3DH_INT1_XH_DIS 0x00
#define LIS3DH_INT1_XL_EN 0x01
#define LIS3DH_INT1_XL_DIS 0x00
// ********************************************************************************

void gsensor_read_xyz(int16_t *x, int16_t *y, int16_t *z);
void pedometer_ctrl_init(void);
void pedometer_ctrl_start(void);
void pedometer_ctrl_stop(void);
void gsensor_clear_interrupt(void);

uint8_t pedometer_get_gsensor_id(void);

bool gsensor_exist_check(void);
void gsensor_to_normal_work(void);
void pedometer_algorithm_process(void);

void pedometer_app_cmd_test(uint8_t *p_data);
bool accelerometer_init(void);
#endif
